package fileHash

import (
	"crypto/sha256"
	"crypto/sha512"
	"encoding/hex"
	"fmt"
	"io"
	"mime/multipart"
	"os"
)

/**
 * @Author Administrator
 * @Description 计算文件hash值,修复1.0大文件内存溢出的问题
 * @Date 2023/8/2 21:17
 * @Version 2.0
 */

// GetFileHash512
//
//	@Description: 利用Hash512算法计算文件的hash值
//	@param:: path 文件的路径
//	@return string 返回的hash值
//	@return error 异常
func GetFileHash512(path string) (string, error) {
	f, err := os.Open(path)
	if err != nil {
		return "", err
	}
	defer f.Close()

	hasher := sha512.New()
	if _, err := io.Copy(hasher, f); err != nil {
		return "", err
	}

	hash := hasher.Sum(nil)
	return hex.EncodeToString(hash), nil
}

// GetFileHash256
//
//	@Description: 利用Hash256算法计算文件的hash值
//	@param: path 文件的路径
//	@return string 返回的hash值
//	@return error 异常
func GetFileHash256(path string) (string, error) {
	f, err := os.Open(path)
	if err != nil {
		return "", err
	}
	defer f.Close()

	hasher := sha256.New()
	buf := make([]byte, 4096) // 4KB buffer
	for {
		n, err := f.Read(buf)
		if err != nil && err != io.EOF {
			return "", err
		}
		if n == 0 {
			break
		}
		_, err = hasher.Write(buf[:n])
		if err != nil {
			return "", err
		}
	}

	hash := hasher.Sum(nil)
	return hex.EncodeToString(hash), nil
}

func main() {
	path := "path/to/file.txt" // 替换为你自己的文件路径
	hash, err := GetFileHash512(path)
	if err != nil {
		fmt.Println("计算哈希失败:", err)
		return
	}

	fmt.Println("SHA-512哈希:", hash)
}

// GetFileHash256ByMultipart
//
//	@Description: 通过多部分获取文件哈希
//	@param: fileHeader 文件
//	@return string hash结果
//	@return error
func GetFileHash256ByMultipart(fileHeader *multipart.FileHeader) (string, error) {
	file, err := fileHeader.Open()
	if err != nil {
		return "", err
	}
	defer file.Close()

	hash := sha256.New()
	if _, err := io.Copy(hash, file); err != nil {
		return "", err
	}

	hashInBytes := hash.Sum(nil)
	hashString := hex.EncodeToString(hashInBytes)

	return hashString, nil
}
